package com.mall.common.utils;

import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.mall.common.exception.UnauthorizedException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.security.KeyPair;
import java.util.Date;

/**
 * JWT工具类，用于生成和解析JWT令牌
 */
@Component
public class JwtUtils {

    @Value("${jwt.secret}")
    private String jwtSecret;

    private final JWTSigner jwtSigner;

    // 构造函数初始化签名器
    public JwtUtils(@Value("${jwt.secret}") String jwtSecret) {
        this.jwtSecret = jwtSecret;
        this.jwtSigner = JWTSignerUtil.hs256(jwtSecret.getBytes());
    }

    /**
     * 生成JWT令牌
     * @param userId 用户ID
     * @param expireTime 过期时间（毫秒）
     * @return JWT令牌
     */
    public String createToken(Long userId, long expireTime) {
        // 计算过期时间
        long expireAt = System.currentTimeMillis() + expireTime;
        // 生成令牌
        return JWT.create()
                .setPayload("userId", userId)
                .setExpiresAt(new Date(expireAt))
                .setSigner(jwtSigner)
                .sign();
    }

    /**
     * 从JWT令牌中获取用户ID
     * 解析JWT
     * @param token JWT令牌
     * @return 用户ID
     */
    public Long parseToken(String token) {
        // 1.校验token是否为空
        if (token == null) {
            throw new UnauthorizedException("未登录");
        }
        // 2.校验并解析jwt
        JWT jwt;
        try {
            jwt = JWT.of(token).setSigner(jwtSigner);
        } catch (Exception e) {
            throw new UnauthorizedException("无效的token", e);
        }
        // 2.校验jwt是否有效
        if (!jwt.verify()) {
            // 验证失败
            throw new UnauthorizedException("无效的token");
        }
        // 3.校验是否过期
        try {
            JWTValidator.of(jwt).validateDate();
        } catch (ValidateException e) {
            throw new UnauthorizedException("token已经过期");
        }
        // 4.数据格式校验
        Object userIdPayload = jwt.getPayload("userId");
        if (userIdPayload == null) {
            // 数据为空
            throw new UnauthorizedException("无效的token");
        }
        // 5.返回用户ID
        return Long.valueOf(userIdPayload.toString());
    }

    /**
     * 验证JWT令牌
     * @param token JWT令牌
     * @return 是否有效
     */
    public boolean verifyToken(String token) {
        try {
            JWT.of(token)
                    .setSigner(getJwtSigner())
                    .verify();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    // 懒加载签名器
    private JWTSigner getJwtSigner() {
        return JWTSignerUtil.hs256(jwtSecret.getBytes());
    }
}